#!/usr/bin/python

import os, sys
import subprocess as sub

entry_path = os.path.abspath(os.curdir)
base_path = "/etc/openvpn/easy-rsa";

def newClient(clientName = None):
    os.chdir(base_path);
#create key
    if clientName == None:
        clientName = input("[?] Client name\n>>> ");

    with open("pki/index.txt") as file:
        for line in file:
            if line.find(clientName) > -1:
                print(f"[!] Client {clientName} is already exist");
                exit(1);

    print(f"[~] Creating keys for {clientName}");

    isPasswd = input("[?] Use password [y/N]\n>>>");

    ersa_cmd = f"./easyrsa --batch build-client-full \"{clientName}\""
    
    os.popen(ersa_cmd if isPasswd == 'y' or isPasswd == 'Y' else ersa_cmd + " nopass").read();

#create config

    config = [];
    print(f"[~] Copy template config ...");
    with open("../client-template.txt") as tmpl:
        for line in tmpl:
            config.append(line);

    # change ip

    # i'll do it later ...

    # add keys

    print(f"[~] Adding keys to config ...");

    with open("pki/ca.crt") as ca:
        config.append("<ca>");
        for line in ca:
            config.append(line);
        config.append("</ca>");


    with open(f"pki/issued/{clientName}.crt") as client_crt:
        config.append("<cert>");
        
        allow_write = False;
        for line in client_crt:
        
            if line == "-----BEGIN CERTIFICATE-----": allow_write = not allow_write;
            if allow_write:
                config.append(line);
        
        config.append("</cert>");

    with open("../server.conf") as ovconf:
        if ovconf.read().find("tls-crypt") > -1:
            config.append("<tls-crypt>");
            tls = open("../tls-crypt.key");
            for line in tls:
                config.append(line);    
            tls.close();
            config.append("</tls-crypt>");
        elif ovconf.read().find("tls-auth") > -1:
            config.append("<tls-auth>");
            tls = open("../tls-auth.key");
            for line in tls:
                config.append(line);    
            tls.close();
            config.append("</tls-auth>");

    with open(f"{entry_path}/{clientName}.ovpn", "w") as new_config:
        for i in config:
            new_config.write(i);

    print(f"[+] Client {clientName} successful added!");
    
    return 0;

def restoreConfig():
    pass
    
def revokeClient(clientName = None):
    os.chdir(base_path);

    index = [];

    with open("pki/index.txt") as file:
        for line in file:
            index.append(line);

    for i in index:
        print(f"[>] {i[62:-1]}");

    if clientName == None:
        clientName = input("[?] Client name\n>>> ");

    for i in index:
        if index[i].find(clientName) > -1: break
    else:
        print(f"[!] Client {clientName} does not exist!");
        exit(1);
        

    print(f"[~] Deleting {clientName} from index.txt ...");
    with open("pki/index.txt", "w") as file:
        for i in index:
            file.write(i);

    print(f"[~] Deleting {clientName} keys ...");

    keyPaths = {
        "./pki/private" : "key",
        "./pki/reqs" : "req",
        "./pki/issued" : "crt",
        "./pki/inline" : "inline"
    };

    for path in keyPaths:
        try:
            file = f"{path}/{clientName}.{keyPaths[path]}"
            os.remove(file);
        except FileNotFoundError:
            print(f"[!] File {file} not found");

    print(f"[+] Client {clientName} succeful removed");

def init():
    if os.getuid() > 0:
        print("[!] Permission denied!");
        exit(1);

    required_files = [
        "/etc/openvpn/easy-rsa/pki/index.txt",
        "/etc/openvpn/easy-rsa/easyrsa",
        "/etc/openvpn/server.conf",
    ];
    for file in required_files:
        if not os.path.exists(file):
            print(f"[!] File {file} not found");
            exit(1);


    
init();

if len(sys.argv) <= 1:
    print("[+] 1: add client\n\
[~] 2: remove client\n\
[-] 3: restore config of existing user");
    ack = int(input("[?] Select action [1-2]\n>>> "));
    match ack:
        case 1:
            newClient();
        case 2:
            revokeClient();
        case 3:
            restoreConfig();
        case _:
            printf(f"[!] Unknown action");
else:
    print(f"[!] There is no args! For now...");
